﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Experts.Model;
using System.Data;
using System.Data.SqlTypes;
using Experts.Framework.Mapping;

namespace DBUtility
{
    /// <summary>
    /// 只要是同一个T，只会初始化一次，然后静态保存下来不同的T，
    /// 会不同的初始化，然后分别保存，互不干扰
    /// 这不就是一个很适合当前场景的缓存
    /// 泛型缓存的性能是超高的
    /// 字典缓存是hash存储，数据量不多读写都比较快，数据多了性能会严重下降的
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SqlBuilder<T> where T : BaseModel
    {
        private static string FindOneSql = null;
        private static string InsertSql = null;
        private static string UpdateSql = null;

        static SqlBuilder()
        {
            {
                Type type = typeof(T);
                string columnStrings = string.Join(",", type.GetProperties().Select(p => $"[{p.GetMappingName()}]"));
                FindOneSql = $@"select {columnStrings} from [{type.GetMappingName()}] where Id=@Id";
            }
            {
                Type type = typeof(T);
                string columnStrings = string.Join(",", type.GetProperties().FilterKey().Select(p => $"[{p.GetMappingName()}]"));
                string valueStrings = string.Join(",", type.GetProperties().FilterKey().Select(p => $"@{p.GetMappingName()}"));
                InsertSql = $"insert into [{type.GetMappingName()}] ({columnStrings}) values ({valueStrings})";
            }
            {
                Type type = typeof(T);
                string columnValues = string.Join(",", type.GetProperties().FilterKey().Select(p => $"[{p.GetMappingName()}]=@{p.GetMappingName()}"));
                UpdateSql = $"update [{type.GetMappingName()}] set {columnValues} where Id=@Id";
            }
        }
        /// <summary>
        /// 对外提供的获取方法
        /// </summary>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        public static string GetSql(SqlType sqlType)
        {
            switch(sqlType)
            {
                case SqlType.FindOne:
                    return FindOneSql;
                case SqlType.Insert:
                    return InsertSql;
                case SqlType.Update:
                    return UpdateSql;
                default:
                    throw new Exception("wrong SqlType");
            }
        }
        /// <summary>
        /// 枚举方便传参数
        /// </summary>
        public enum SqlType
        {
            FindOne,
            Insert,
            Update
        }
    }
}
